/*
 * @Author: liutongchao 1923236391@qq.com
 * @Date: 2023-05-31 13:44:24
 * @LastEditors: liutongchao 1923236391@qq.com
 * @LastEditTime: 2025-03-24 15:14:10
 * @FilePath: \greenbeeadmin\controllers\admin\service\userService.go
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
package service

import (
	"fmt"
	greebeeUtils "greenbeeadmin/controllers/greenbee/utils"
	"greenbeeadmin/models"
	"strconv"
	"strings"

	"github.com/beego/beego/v2/client/orm"
)

/**
 * @description: 后台用户 service
 * @return {*}
 */
type AdminUserService struct {
	AdminBaseService
}

type AdminUserSearchParams struct {
	Username string
}

/**
 * @description: 获取后台用户列表数据
 * @param {map[string]string} params 搜索参数
 * @param {string} field 要查询的后台用户字段 全部数据传 “*”
 * @return {*}
 */
func (s *AdminUserService) GetList(params map[string]string, field []string) ([]models.AdminUser, float64, error) {
	tableName := new(models.AdminUser).GetTableName()
	var users []models.AdminUser
	username, ok := params["username"]
	where := "is_del =0"
	if ok {
		where += " and user_name like '%" + username + "%'"
	}
	pg, ok := params["page"]
	if ok {
		Page, _ = strconv.ParseFloat(pg, 64)
	}
	limit_str, ok := params["limit"]
	if ok {
		Limit, _ = strconv.ParseFloat(limit_str, 64)
	}
	//查询用户数据
	o := orm.NewOrm()
	//获取总条数
	var total_row float64
	o.Raw("select  count(id) from " + tableName + " as n where " + where).QueryRow(&total_row)
	//获取偏移值
	offset := greebeeUtils.GetPageOffset(Page, Limit, total_row)
	// 获取 QueryBuilder 对象. 需要指定数据库驱动参数。
	// 第二个返回值是错误对象，在这里略过
	qb, _ := orm.NewQueryBuilder("mysql")
	// 构建查询对象
	qb.Select(field...).
		From(tableName).
		Where(where).
		OrderBy("id").Desc().
		Limit(int(Limit)).Offset(int(offset))

	// 导出 SQL 语句
	sql := qb.String()

	// 执行 SQL 语句
	o.Raw(sql).QueryRows(&users)

	return users, total_row, nil
}

/**
 * @description: 用户删除
 * @param {int} id
 * @return {*}
 */
func (s *AdminUserService) UserDelete(id int) int64 {
	o := orm.NewOrm()
	user := models.AdminUser{Id: id}
	if o.Read(&user) == nil && user.Is_admin == 0 {
		// 删除用户的角色
		s.DelAdminuserRoleId(id)
		//user.Is_del = 1
		if num, err := o.Delete(&user, "Id"); err == nil {
			fmt.Println(num)
			return num
		}
	}
	return 0
}

/**
 * @description: 用户删除 批量
 * @param {int} id
 * @return {*}
 */
func (s *AdminUserService) UserDeletes(ids []string) int64 {
	var num int64
	o := orm.NewOrm()
	for _, id := range ids {
		id_int, _ := strconv.Atoi(id)
		user := models.AdminUser{Id: id_int}
		if o.Read(&user) == nil && user.Is_admin == 0 {
			// 删除用户的角色
			s.DelAdminuserRoleId(id_int)
			//user.Is_del = 1
			if num, err := o.Delete(&user, "Id"); err == nil {
				fmt.Println(num)
				num += num
			}
		}
	}
	return num
}

/**
 * @description: 用户添加
 * @param {models.AdminUser} userdata
 * @return {*}
 */
func (s *AdminUserService) UserAdd(userdata models.AdminUser) int64 {
	o := orm.NewOrm()
	id, err := o.Insert(&userdata)
	if err == nil {
		//fmt.Println(id)
	}
	return id
}

/**
 * @description: 用户编辑
 * @param {models.AdminUser} userdata
 * @return {*}
 */
func (s *AdminUserService) UserEdit(userdata models.AdminUser, uid int, field []string) int64 {
	o := orm.NewOrm()
	user := models.AdminUser{Id: uid}
	if o.Read(&user, "Id") == nil {
		userdata.Id = uid
		if num, err := o.Update(&userdata, field...); err == nil {
			fmt.Println(num)
			return num
		}
	}
	return 0
}

/**
 * @description: 获取用户
 * @param {models.AdminUser} userdata
 * @param {[]string} field
 * @return {*}
 */
func (s *AdminUserService) GetUser(userdata models.AdminUser, field []string) (models.AdminUser, error) {
	o := orm.NewOrm()
	err := o.Read(&userdata, field...)
	if err == orm.ErrNoRows {
		fmt.Println("查询不到")
	} else if err == orm.ErrMissPK {
		fmt.Println("找不到主键")
	}
	return userdata, err
}

/**
 * @description: 用户角色分配
 * @param {int} adminUserId
 * @param {[]string} roleIds
 * @return {*}
 */
func (s *AdminUserService) UserRoleEmpower(adminUserId int, roleIds []string) int {
	var num int
	o := orm.NewOrm()
	//删除用户下的角色id
	roleUser := models.UserRole{AdminUserId: adminUserId}
	if _, err := o.Delete(&roleUser, "AdminUserId"); err == nil {
		//fmt.Println(num)
		//插入 新角色节点id
		if len(roleIds) > 0 {
			var insertData []models.UserRole
			for _, id := range roleIds {
				id_int, _ := strconv.Atoi(id)
				roleUsers := models.UserRole{AdminUserId: adminUserId, RoleId: id_int}
				insertData = append(insertData, roleUsers)
			}
			successNum, _ := o.InsertMulti(len(insertData), insertData)
			//fmt.Println(err)
			return int(successNum)
		}

	}

	return num
}

// 删除管理员的角色
func (s *AdminUserService) DelAdminuserRoleId(adminUserId int) int64 {
	var num int64
	o := orm.NewOrm()
	//删除用户下的角色id
	roleUser := models.UserRole{AdminUserId: adminUserId}
	if _, err := o.Delete(&roleUser, "AdminUserId"); err == nil {
		num = 1
	}
	return num
}

/**
 * @description: 查询后台用户的 角色id
 * @param {int} adminUserId
 * @return {*}
 */
func (s *AdminUserService) GetUserRoleIds(adminUserId int) []int {
	var data []int
	var userRole models.UserRole
	var userRoles []models.UserRole
	o := orm.NewOrm()
	// 获取 QuerySeter 对象，roleMenu 为表名
	qs := o.QueryTable(userRole.GetTableName())
	num, err := qs.Filter("AdminUserId", adminUserId).All(&userRoles)
	if err == nil && num > 0 {
		for _, v := range userRoles {
			data = append(data, v.RoleId)
		}
	}
	return data
}

// 获取管理员权限
func (s *AdminUserService) GetUserAuthorizationIds(userid int) []int {
	var data []int
	if userid <= 0 {
		return data
	}

	// 超级管理员处理
	userField := []string{"Id"}
	var userdata = models.AdminUser{Id: userid}
	user, _ := s.GetUser(userdata, userField)
	//超级管理员直接返回所有菜单
	if user.Is_admin == 1 {
		var menuservice MenuService
		var params map[string]string
		field := []string{"id", "created_at", "updated_at", "authority_name", "menu_icon", "parent_id", "order_number", "menu_url", "authority", "is_menu", "status"}
		menu_data, err := menuservice.GetAdminMenuList(params, field)
		if err == nil && len(menu_data) > 0 {
			for _, v := range menu_data {
				data = append(data, v.Id)
			}
			return data
		}
	}

	uid := strconv.Itoa(userid)
	//查询角色数据
	o := orm.NewOrm()
	// 获取 QueryBuilder 对象. 需要指定数据库驱动参数。
	// 第二个返回值是错误对象，在这里略过
	qb, _ := orm.NewQueryBuilder("mysql")
	// 构建查询对象
	var userRole models.UserRole
	var roleMenu models.RoleMenu
	userRoleTableName := userRole.GetTableName()

	roleMenuTableName := roleMenu.GetTableName()
	where := userRole.GetTableName() + ".admin_user_id ='" + uid + "'"

	qb.Select(roleMenuTableName + ".admin_menu_id").
		From(userRoleTableName).
		LeftJoin(roleMenuTableName).On(userRoleTableName + ".role_id = " + roleMenuTableName + ".role_id").
		Where(where).GroupBy(roleMenuTableName + ".admin_menu_id")

	// 导出 SQL 语句
	sql := qb.String()

	// 执行 SQL 语句
	type AuthorizationId struct {
		models.UserRole
		models.RoleMenu
	}
	var authorizationIds []AuthorizationId
	o.Raw(sql).QueryRows(&authorizationIds)

	if len(authorizationIds) > 0 {
		for _, v := range authorizationIds {
			data = append(data, v.AdminMenuId)
		}
	}

	return data
}

// 获取管理员菜单节点
func (s *AdminUserService) GetUserAuthorizationUrls(userid int) []string {
	var data []string
	if userid <= 0 {
		return data
	}
	uid := strconv.Itoa(userid)
	//查询角色数据
	o := orm.NewOrm()
	// 获取 QueryBuilder 对象. 需要指定数据库驱动参数。
	// 第二个返回值是错误对象，在这里略过
	qb, _ := orm.NewQueryBuilder("mysql")
	// 构建查询对象
	var userRole models.UserRole
	var roleMenu models.RoleMenu
	var adminMenu models.AdminMenu
	userRoleTableName := userRole.GetTableName()
	roleMenuTableName := roleMenu.GetTableName()
	adminMenuTableName := adminMenu.GetTableName()
	where := userRole.GetTableName() + ".admin_user_id ='" + uid + "'"

	qb.Select(adminMenuTableName+".*", roleMenuTableName+".admin_menu_id").
		From(userRoleTableName).
		LeftJoin(roleMenuTableName).On(userRoleTableName + ".role_id = " + roleMenuTableName + ".role_id").
		LeftJoin(adminMenuTableName).On(roleMenuTableName + ".admin_menu_id = " + adminMenuTableName + ".id").
		Where(where).GroupBy(roleMenuTableName + ".admin_menu_id")

	// 导出 SQL 语句
	sql := qb.String()

	// 执行 SQL 语句
	type AuthorizationId struct {
		models.UserRole
		models.RoleMenu
		models.AdminMenu
	}
	var authorizationIds []AuthorizationId
	o.Raw(sql).QueryRows(&authorizationIds)

	if len(authorizationIds) > 0 {
		for _, v := range authorizationIds {
			if v.MenuUrl != "" {
				menuUrl := strings.Replace(v.MenuUrl, ".html", "", -1)
				index := strings.Index(menuUrl, "/")
				if index != 0 {
					urls := "/" + menuUrl
					data = append(data, urls)
				} else {
					data = append(data, menuUrl)
				}

			}
		}
	}

	return data
}
